package cn.gs.global.server.meta;

// @author gs
import cn.gs.db.HibernateUtil;
import cn.gs.db.ObjectTransaction;
import cn.gs.db.BoolTransaction;
import cn.gs.exchanger.ExchangerException;
import cn.gs.global.table.meta.IIdName;
import cn.gs.util.set.ArrayUtil;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.Query;

public class IdNameServer<T extends IIdName> {

    Class<T> clazz;
    HibernateUtil util;
    String tableName;

    public IdNameServer(Class<T> clazz, String tableName, HibernateUtil util) {
        this.clazz = clazz;
        this.tableName = tableName;
        this.util = util;
    }

    public int[] create(final String... name) throws ExchangerException {
        return (int[]) util.transaction(new ObjectTransaction() {

            @Override
            public Object work() throws RuntimeException {
                int[] v = new int[name.length];
                for (int i = 0; i < name.length; ++i) {
                    try {
                        T ogn = clazz.newInstance();
                        ogn.setName(name[i]);
                        util.saveOrUpdate(ogn);
                        v[i] = ogn.getId();
                    } catch (InstantiationException | IllegalAccessException ex) {
                        Logger.getLogger(IdNameServer.class.getName()).log(Level.SEVERE, "create_fail", ex);
                    }
                }
                return v;
            }
        });
    }

    public int[] search(String sch) {
        Query q = util.query("FROM " + tableName + " WHERE sch LIKE :sch");
        q.setParameter("sch", "%" + sch + "%");
        List<T> ogns = q.list();
        int[] ret = new int[ogns.size()];
        int i = 0;
        for (T o : ogns) {
            ret[i++] = o.getId();
        }
        return ret;
    }

    public String[] names(int... id) {
        List<Integer> ids = ArrayUtil.array2List(id);
        List<T> ogns = util.get(clazz, ids);
        String[] idss = new String[ogns.size()];
        int i = 0;
        for (T o : ogns) {
            idss[i++] = o.getName();
        }
        return idss;
    }

    public void setName(final int id, final String name) {
        util.transaction(new BoolTransaction() {

            @Override
            public boolean work() {
                T t = util.get(clazz, id);
                t.setName(name);
                util.saveOrUpdate(t);
                return true;
            }
        });
    }

    public void delete(final int... id) {
        util.transaction(new BoolTransaction() {

            @Override
            public boolean work() {
                List<Integer> ids = ArrayUtil.array2List(id);
                List<T> ogns = util.get(clazz, ids);
                for (T o : ogns) {
                    o.setDeleted(true);
                }
                util.saveOrUpdate(ogns);
                return true;
            }
        });
    }

    public boolean[] isDeleted(int... id) {
        List<Integer> ids = ArrayUtil.array2List(id);
        List<T> ogns = util.get(clazz, ids);
        boolean[] idss = new boolean[ogns.size()];
        int i = 0;
        for (T o : ogns) {
            idss[i++] = o.isDeleted();
        }
        return idss;
    }
}
